"""
规范修正服务

提供规范澄清和修正的核心服务功能
"""

import json
from pathlib import Path
from typing import List, Dict, Any, Optional
from modules.specification_fixer.services.spec_parser import SpecificationParser
from modules.specification_fixer.core.scope_analyzer import ScopeAnalyzer
from modules.specification_fixer.models.requirement_scope import RequirementScope
from modules.specification_fixer.utils.logger import get_logger

logger = get_logger(__name__)


class FixService:
    """规范修正服务"""

    def __init__(self):
        """初始化服务"""
        self.spec_parser = SpecificationParser()
        self.scope_analyzer = ScopeAnalyzer()
        # 延迟导入避免循环依赖
        self.validation_service = None
        self.report_service = None

    def clarify_requirement_scope(self, requirements: List[Dict[str, Any]]) -> Dict[str, Any]:
        """澄清需求范围"""
        if not requirements:
            raise ValueError("需求列表不能为空")

        logger.info(f"开始澄清需求范围，共 {len(requirements)} 个需求")

        # 转换为分析器需要的格式
        requirements_dict = {}
        for req in requirements:
            req_id = req.get('id', f"req_{len(requirements_dict)}")
            requirements_dict[req_id] = req

        try:
            # 识别核心功能
            core_functions = self.scope_analyzer.identify_core_functions(requirements_dict)

            # 识别排除功能
            excluded_functions = self.scope_analyzer.identify_excluded_functions(requirements_dict)

            # 生成范围定义理由
            justification = self._generate_justification(core_functions, excluded_functions, requirements)

            # 创建范围定义
            scope = self.scope_analyzer.create_requirement_scope(
                core_functions=core_functions,
                excluded_functions=excluded_functions,
                justification=justification
            )

            # 提取范围边界
            scope_boundaries = self.scope_analyzer.extract_scope_boundaries(requirements_dict)

            # 分类需求
            retained_requirements = [
                req for req in requirements
                if req.get('id') in core_functions
            ]
            removed_requirements = [
                req for req in requirements
                if req.get('id') in excluded_functions
            ]

            result = {
                'scope_definition': scope,
                'scope_boundaries': scope_boundaries,
                'retained_requirements': retained_requirements,
                'removed_requirements': removed_requirements,
                'clarification_summary': self._generate_summary(scope, retained_requirements, removed_requirements)
            }

            logger.info(f"范围澄清完成，保留 {len(retained_requirements)} 个核心需求，移除 {len(removed_requirements)} 个非核心需求")
            return result

        except Exception as e:
            logger.error(f"需求范围澄清失败: {e}")
            raise

    def clarify_requirement_scope_from_file(self, file_path: str) -> Dict[str, Any]:
        """从文件澄清需求范围"""
        logger.info(f"从文件澄清需求范围: {file_path}")

        # 解析规范文件
        requirements = self.spec_parser.parse_requirements(file_path)

        # 执行范围澄清
        return self.clarify_requirement_scope(requirements)

    def save_scope(self, scope: RequirementScope, file_path: str) -> None:
        """保存范围定义"""
        try:
            file_path = Path(file_path)
            file_path.parent.mkdir(parents=True, exist_ok=True)

            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(scope.to_dict(), f, ensure_ascii=False, indent=2)

            logger.info(f"范围定义已保存到: {file_path}")

        except Exception as e:
            logger.error(f"保存范围定义失败: {e}")
            raise

    def load_scope(self, file_path: str) -> RequirementScope:
        """加载范围定义"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)

            scope = RequirementScope.from_dict(data)
            logger.info(f"已加载范围定义: {scope.scope_name}")
            return scope

        except Exception as e:
            logger.error(f"加载范围定义失败: {e}")
            raise

    def analyze_specification_quality(self, file_path: str) -> Dict[str, Any]:
        """分析规范质量"""
        logger.info(f"分析规范质量: {file_path}")

        # 解析规范
        requirements = self.spec_parser.parse_requirements(file_path)
        validation = self.spec_parser.validate_specification(file_path)

        # 分析需求分布
        category_stats = {}
        priority_stats = {}

        for req in requirements:
            category = req.get('category', 'unknown')
            priority = req.get('priority', 'unknown')

            category_stats[category] = category_stats.get(category, 0) + 1
            priority_stats[priority] = priority_stats.get(priority, 0) + 1

        # 计算质量得分
        quality_score = self._calculate_quality_score(validation, category_stats, priority_stats)

        # 生成改进建议
        suggestions = self._generate_quality_suggestions(category_stats, priority_stats, validation)

        return {
            'file_path': file_path,
            'total_requirements': len(requirements),
            'category_distribution': category_stats,
            'priority_distribution': priority_stats,
            'validation_result': validation,
            'quality_score': quality_score,
            'suggestions': suggestions
        }

    def generate_clarification_report(self, clarification_result: Dict[str, Any]) -> Dict[str, Any]:
        """生成澄清报告"""
        scope = clarification_result['scope_definition']
        retained = clarification_result['retained_requirements']
        removed = clarification_result['removed_requirements']

        report = {
            'report_info': {
                'generated_at': scope.updated_at.isoformat(),
                'scope_name': scope.scope_name,
                'scope_id': scope.scope_id
            },
            'scope_summary': scope.get_scope_summary(),
            'changes_summary': {
                'total_requirements': len(retained) + len(removed),
                'retained_count': len(retained),
                'removed_count': len(removed),
                'retention_rate': len(retained) / (len(retained) + len(removed)) * 100 if (retained or removed) else 0
            },
            'detailed_changes': {
                'retained_requirements': [
                    {
                        'id': req.get('id'),
                        'description': req.get('description'),
                        'category': req.get('category'),
                        'priority': req.get('priority')
                    }
                    for req in retained
                ],
                'removed_requirements': [
                    {
                        'id': req.get('id'),
                        'description': req.get('description'),
                        'category': req.get('category'),
                        'reason': self._get_removal_reason(req)
                    }
                    for req in removed
                ]
            },
            'scope_boundaries': clarification_result['scope_boundaries'],
            'justification': scope.justification,
            'next_steps': self._generate_next_steps(scope)
        }

        return report

    def _generate_justification(self, core_functions: List[str], excluded_functions: List[str],
                              requirements: List[Dict[str, Any]]) -> str:
        """生成范围定义理由"""
        justification_parts = []

        # 基于MoSCoW分类法的理由
        justification_parts.append("基于MoSCoW分类法进行需求范围分析，")

        # 核心功能说明
        if core_functions:
            core_count = len(core_functions)
            justification_parts.append(f"识别出 {core_count} 项核心功能，")

        # 排除功能说明
        if excluded_functions:
            excluded_count = len(excluded_functions)
            justification_parts.append(f"排除 {excluded_count} 项非核心功能，")

        # 范围聚焦说明
        justification_parts.append("专注于文档分析模块的核心价值，确保功能聚焦和范围清晰。")

        # 具体分析结果
        core_ratio = len(core_functions) / len(requirements) * 100 if requirements else 0
        justification_parts.append(f"核心功能占比 {core_ratio:.1f}%，符合模块化架构原则。")

        return ''.join(justification_parts)

    def _generate_summary(self, scope: RequirementScope, retained: List[Dict], removed: List[Dict]) -> str:
        """生成澄清摘要"""
        summary_parts = []

        summary_parts.append(f"需求范围澄清完成：")
        summary_parts.append(f"- 范围名称：{scope.scope_name}")
        summary_parts.append(f"- 保留核心功能：{len(retained)} 项")
        summary_parts.append(f"- 移除非核心功能：{len(removed)} 项")
        summary_parts.append(f"- 包含功能类别：{', '.join(scope.scope_boundary.get('includes', []))}")
        summary_parts.append(f"- 排除功能类别：{', '.join(scope.scope_boundary.get('excludes', []))}")

        return '\n'.join(summary_parts)

    def _get_removal_reason(self, requirement: Dict[str, Any]) -> str:
        """获取需求移除理由"""
        category = requirement.get('category', 'unknown')
        description = requirement.get('description', '')

        if category == 'non_core':
            return "非核心功能，超出模块范围"
        elif any(keyword in description for keyword in ['资产', '管理', '账号', '密码']):
            return "属于资产管理或用户管理，非文档分析核心功能"
        else:
            return "功能优先级较低，可在后续版本考虑"

    def _calculate_quality_score(self, validation: Dict[str, Any],
                               category_stats: Dict[str, int],
                               priority_stats: Dict[str, int]) -> float:
        """计算规范质量得分"""
        score = 100.0

        # 基于验证结果扣分
        for issue in validation.get('issues', []):
            score -= 20

        for warning in validation.get('warnings', []):
            score -= 10

        # 基于需求分布扣分
        total_reqs = sum(category_stats.values())
        if total_reqs > 0:
            core_ratio = category_stats.get('core', 0) / total_reqs
            if core_ratio < 0.3:
                score -= 15  # 核心功能比例过低

        # 基于优先级分布扣分
        if priority_stats.get('low', 0) > priority_stats.get('high', 0):
            score -= 10  # 低优先级功能过多

        return max(0.0, score)

    def _generate_quality_suggestions(self, category_stats: Dict[str, int],
                                    priority_stats: Dict[str, int],
                                    validation: Dict[str, Any]) -> List[str]:
        """生成质量改进建议"""
        suggestions = []

        # 基于验证结果的建议
        for issue in validation.get('issues', []):
            suggestions.append(f"需要修复: {issue}")

        for warning in validation.get('warnings', []):
            suggestions.append(f"建议改进: {warning}")

        # 基于分布的建议
        total_reqs = sum(category_stats.values())
        if total_reqs > 0:
            core_ratio = category_stats.get('core', 0) / total_reqs
            if core_ratio < 0.3:
                suggestions.append("建议增加核心功能需求的比例")

        unknown_count = category_stats.get('unknown', 0)
        if unknown_count > total_reqs * 0.2:
            suggestions.append("建议明确更多需求的分类")

        return suggestions

    def _generate_next_steps(self, scope: RequirementScope) -> List[str]:
        """生成下一步行动建议"""
        steps = []

        steps.append("1. 审查生成的范围定义，确认核心功能列表")
        steps.append("2. 验证排除功能列表，确保没有误删重要需求")
        steps.append("3. 与相关利益方确认范围边界")
        steps.append("4. 更新项目文档和需求规格说明")
        steps.append("5. 基于澄清后的范围制定详细实施计划")

        # 基于复杂度的建议
        complexity = self.scope_analyzer.analyze_scope_complexity(scope)
        if complexity['level'] == '复杂':
            steps.insert(0, "0. 考虑将复杂范围拆分为多个子范围")

        return steps